package com.vm.utils;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;

import com.vm.commons.VMConst;
import com.vm.db.DownInfoDao;
import com.vm.model.DownInfo;
import com.vm.model.Soft;

import android.content.Context;
import android.os.Environment;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;

public class DownloadThread extends Thread {
	private Handler downHandler;// 自己的handler
	private Handler mainHandler;// 主线程的Handler
	private Handler thirdHandler; // 第三个Handler，详情页或下载管理
	public boolean isPause = true; // 是否暂停true为暂停
	public boolean isResume = true;// 是否继续下载true为暂停状态̬

	private int FileSize = 0;// 文件总字节数

	private int done;
	public DownInfoDao dao;

	public DownloadThread(Handler handler) {
		this.thirdHandler = handler;
	}

	public void setMainHandler(DownInfoDao dao, Handler mainHandler) {
		this.dao = dao;
		this.mainHandler = mainHandler;
	}

	public void setThirdHandler(DownInfoDao dao, Handler mainHandler) {
		this.dao = dao;
		this.thirdHandler = mainHandler;
	}

	/**
	 * 新构造函数
	 * 
	 * @param dao
	 * @param mainHandler
	 */
	public DownloadThread(DownInfoDao dao, Handler mainHandler) {
		this.dao = dao;
		this.mainHandler = mainHandler;
	}

	/**
	 * 旧方法,即将删除
	 * 
	 * @param context
	 * @param mainHandler
	 */
	public DownloadThread(Context context, Handler mainHandler) {
		dao = new DownInfoDao(context);
		this.mainHandler = mainHandler;
	}

	public synchronized Handler getDownHandler() {
		return downHandler;
	}

	public void setSuspend(boolean isPause) {
		if (!isPause) {
			synchronized (dao) {
				dao.notifyAll();
			}
		}
		this.isPause = isPause;
	}

	@Override
	public void run() {
		Looper.prepare(); // 默认一个线程里面不存在消息循环，需要调用Looper.prepare()来给线程创建一个消息循环
		downHandler = new Handler() {
			@Override
			public void handleMessage(Message msg) {
				switch (msg.what) {// 看看主线程给我发什么消息？
				case 100:// 100:开始下载
					isPause = false;
					isResume = false;
					preDown((Soft) msg.obj, 0);
					break;
				case 200:// 200:暂停
					isPause = true;
					isResume = true;
					break;
				default:
					break;
				}
				super.handleMessage(msg);
			}
		};
		Looper.loop();// Looper.loop();//调用Looper.loop()来使消息循环起作用，从消息队列里取消息，处理消息
	}

	// 下载方法
	public void preDown(Soft soft, long startPosition) {
		try {

			// String fileUrl = VMConst.DOWN_URL + soft.getId() + "&userId="
			// + CurrentUser.USERID;

			String fileUrl = VMConst.URL + soft.getApkUrl();
			/**
			 * 获取文件信息名称
			 */
			URL url = null;
			url = new URL(fileUrl);
			HttpURLConnection httpURLConnection = (HttpURLConnection) url
					.openConnection();

			// String fileName = fileUrl.substring(fileUrl.lastIndexOf("/") + 1,
			// fileUrl.indexOf("&"));
			// String decodeString = URLDecoder.decode(fileName, "UTF-8");
			// String lastFilename = decodeString.substring(19);

			if (isResume) {
				// 网络上的文件，我怎么能够从指定位置开始下载呢
				httpURLConnection.setRequestProperty("Range", "bytes=" + done
						+ "-" + FileSize);
			} else {
				// 得到文件大小（字节）
				int fileSize = httpURLConnection.getContentLength();
				FileSize = fileSize;
				// 告诉主线程开始下载了
				Message msgStart = new Message();
				msgStart.what = 500;
				msgStart.arg1 = fileSize;
				if (mainHandler != null) {
					mainHandler.sendMessage(msgStart);
				}
				if (thirdHandler != null) {
					thirdHandler.sendMessage(msgStart);
				}
			}

			startDown(fileUrl, soft);

		} catch (MalformedURLException e) {
			Message msg = new Message();
			msg.what = 800;
			if (mainHandler != null) {
				mainHandler.sendMessage(msg);
			}
			if (thirdHandler != null) {
				thirdHandler.sendMessage(msg);
			}
			e.printStackTrace(); // To change body of catc0h statement use File
									// | Settings | File Templates.
		} catch (IOException e) {
			Message msg = new Message();
			msg.what = 700;
			if (mainHandler != null) {
				mainHandler.sendMessage(msg);
			}
			if (thirdHandler != null) {
				thirdHandler.sendMessage(msg);
			}
			e.printStackTrace(); // To change body of catch statement use File |
									// Settings | File Templates.

		}

	}

	/**
	 * @param startPosition
	 * @param httpURLConnection
	 * @param info
	 * @param file
	 * @throws FileNotFoundException
	 * @throws IOException
	 */
	private void startDown(String fileUrl, Soft soft)
			throws FileNotFoundException, IOException {

		try {
			URL url = null;
			url = new URL(fileUrl);
			HttpURLConnection httpURLConnection = (HttpURLConnection) url
					.openConnection();

			File file = new File(Environment.getExternalStorageDirectory()
					.getPath() + "/vmclient/" + soft.getName() + ".apk");
			// if(!file.exists()){

			File file2 = new File(Environment.getExternalStorageDirectory()
					.getPath() + "/vmclient/");
			// 判断是否存在父目录，如果没有，自动创建一个
			if (!file2.exists()) {
			}
			{
				file.getParentFile().mkdir();
			}

			if (!file.exists()) {
				file.createNewFile();
			} else {
				if (file.isDirectory()) {
					file.delete();
					file.createNewFile();
				}
			}

			/**
			 * 查询数据库中是否有此下载信息
			 */
			DownInfo info = dao.query(soft.getId());

			if (info != null) {
				// 如果有, 读取当前线程已下载量
				if (info.getCompleted() == 1) {
					info.setCompleted(0);
					done = 0;
				} else {
					done += info.getDone();
				}
				// isPause = info.getIsPause() == 0 ? false : true;
			} else {
				// 如果没有, 则创建一个新记录存入
				// info = new Info(file.getAbsolutePath(), soft.getId(), 0, 0,
				// FileSize);
				info = new DownInfo();
				info.setPath(file.getAbsolutePath());
				info.setSoftId(soft.getId());
				info.setName(soft.getName());
				info.setImageUrl(soft.getImageUrl());
				info.setIsPause(0);
				info.setDone(0);
				info.setApkUrl(soft.getApkUrl());
				info.setApkLength(FileSize);
				dao.insert(info);
			}
			// 指定开始与结束的下载位置

			httpURLConnection.setRequestProperty("Range", "bytes=" + done + "-"
					+ (FileSize - 1));
			RandomAccessFile randomAccessFile = new RandomAccessFile(file, "rw");
			randomAccessFile.seek(info.getDone());
			InputStream inputStream = httpURLConnection.getInputStream();
			byte[] buffer = new byte[1024 * 10];
			int count = 0;

			Message msg = null;
			while ((count = inputStream.read(buffer)) != -1) {

				// 使用线程锁锁定该线程
				synchronized (dao) {
					try {
						if (isPause) {
							dao.wait();
						}
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}

				randomAccessFile.write(buffer, 0, count);
				done += count;
				info.setDone(info.getDone() + count);
				// 记录每个线程已下载的数据量
				dao.update(info);
				// 新线程中用Handler发送消息，主线程接收消息

				if (mainHandler != null) {
					msg = new Message();
					msg.what = 600;
					msg.arg1 = done;
					mainHandler.sendMessage(msg);
				}
				if (thirdHandler != null) {
					msg = new Message();
					msg.what = 600;
					msg.arg1 = done;
					thirdHandler.sendMessage(msg);
				}
			}

			// 循环结束，APK下载完成
			// 新线程中用Handler发送消息，主线程接收消息
			
//			if(done==info.)
			
			msg = new Message();
			msg.what = 1000;
			msg.arg1 = done;
			// 下载完成后发送一条安装消息即可
			if (mainHandler != null) {
				mainHandler.sendMessage(msg);
			} else {
				if (thirdHandler != null) {
					thirdHandler.sendMessage(msg);
				}
			}
			inputStream.close();
			randomAccessFile.close();
			httpURLConnection.disconnect();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			Message msg = new Message();
			msg.what = 700;
			if (mainHandler != null) {
				mainHandler.sendMessage(msg);
			}
			if (thirdHandler != null) {
				thirdHandler.sendMessage(msg);
			}
			e.printStackTrace(); // To change body of catch statement use File |
									// Settings | File Templates.
			e.printStackTrace();
		}

	}

	public void restart() {
		synchronized (dao) {
			if (!isPause) {
				dao.notify();
			}
		}
	}

}
